package cn.com.hhrcw.enterprise.web;

import cn.com.hhrcw.enterprise.params.ApplicationHistoryParams;
import cn.com.hhrcw.enterprise.params.EntryParam;
import cn.com.hhrcw.enterprise.service.EnterpriseService;
import cn.com.hhrcw.enterprise.vo.ApplicationHistoryVO;
import cn.com.hhrcw.enterprise.vo.CvResumeVO;
import cn.com.hhrcw.enterprise.vo.SsUserInfoVO;
import cn.com.hhrcw.entity.*;
import cn.com.hhrcw.mapstruct.*;
import cn.com.hhrcw.position.entity.RecruitmentPosition;
import cn.com.hhrcw.position.service.IRecruitmentPositionService;
import cn.com.hhrcw.service.*;
import cn.com.hhrcw.utils.DateUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.vo.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;

/**
 * 简历库
 *
 * @program: recruit-boot-parent
 * @author: JD
 * @create: 2020-11-06 15:05
 **/
@RestController
@RequestMapping("/en/entryInfo")
@Slf4j
@Validated
public class EnEntryController {

    @Autowired
    private IOpJobService jobService;

    @Autowired
    private IOpDeliveryHistoryService deliveryHistoryService;

    @Autowired
    private EnOpJobConvert jobConvert;

    @Autowired
    private EnCvResumeConvert resumeConvert;

    @Autowired
    EnterpriseService enterpriseService;

    @Autowired
    ICvResumeService resumeService;

    @Autowired
    private IPiInfoService piInfoService;

    @Autowired
    private ICvUserEduInfoService eduInfoService;

    @Autowired
    private EnCvUserEduInfoConvert eduInfoConvert;

    @Autowired
    private EnPiInfoConvert enPiInfoConvert;

    @Autowired
    private ICvUserWorkInfoService workInfoService;

    @Autowired
    private EnCvUserWorkInfoConvert workInfoConvert;

    @Autowired
    private ICvWorkIntentionService workIntentionService;

    @Autowired
    private EnCvWorkIntentionConvert workIntentionConvert;

    @Autowired
    private EnOpDeliveryHistoryConvert deliveryHistoryConvert;

    @Autowired
    private ISysUserDepartService userDepartService;

    @Autowired
    private IOpBrowseHistoryService browseHistoryService;

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Autowired
    IRecruitmentPositionService positionService;

    @Autowired
    IOpShieldingService opShieldingService;

    @Autowired
    private ICvCertificateService cvCertificateService;

    @Autowired
    private EnCvCertificateConvert cvCertificateConvert;

    /**
     * 人才库
     *
     * @param params
     * @return
     */
    @GetMapping("/getUserList")
    @AutoLog(logType = 2, ty = "visit", value = "人才库列表查询")
    public Result<IPage<SsUserInfoVO>> pageResult(EntryParam params) {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        SysUserDepart depart = userDepartService.lambdaQuery().eq(SysUserDepart::getUserId, loginUser.getId()).one();
        Map<String, Object> queryMap = new HashMap<>(16);
        queryMap.put("groupBy", true);
        queryMap.put("companyId", depart.getDepId());
        if(StrUtil.isNotBlank(params.getJobName())){
            List<RecruitmentPosition> positions = positionService.lambdaQuery()
                .select(RecruitmentPosition::getId)
                .like(RecruitmentPosition::getName, params.getJobName())
                .list();
            queryMap.put("positions", positions.stream().map(RecruitmentPosition::getId).toArray());
        }
        if (StrUtil.isNotBlank(params.getDataId())) {
            queryMap.put("deliveryId", params.getDataId().split(","));
        }
        queryMap.put("sysFrom", params.getSysFrom());
        queryMap.put("sex", params.getSex());
        queryMap.put("bsType", params.getBsType());
        queryMap.put("bsId", params.getSsId());
        queryMap.put("maritalStatus", params.getMaritalStatus());
        queryMap.put("state", null);
        int five = 5;
        if (params.getState() != null) {
            if (params.getState() == 0) {
                queryMap.put("state", new Integer[]{0, 1});
            } else if (params.getState() == five) {
                queryMap.put("state", new Integer[]{5, 9});
            } else {
                queryMap.put("state", new Integer[]{params.getState()});
            }
        }
        queryMap.put("name", params.getUserName());
        //            应聘时间范围 0 近三个月 1近半年
        queryMap.put("createTimeBegin", null);
        queryMap.put("createTimeEnd", null);
        Date now = new Date();
        if (params.getTimeState() != null && params.getTimeState() == 0) {
            queryMap.put("createTimeBegin", cn.hutool.core.date.DateUtil.offsetMonth(now, -3));
        } else if (params.getTimeState() != null && params.getTimeState() == 1) {
            queryMap.put("createTimeBegin", cn.hutool.core.date.DateUtil.offsetMonth(now, -6));
        }
        queryMap.put("createTimeEnd", now);
        //工作经验
        if (params.getMinWorkYear() != null && params.getMaxWorkYear() != null) {
            if (params.getMinWorkYear() == 0 && params.getMaxWorkYear() == 0) {
                queryMap.put("jobTimeBegin", null);
                queryMap.put("jobTimeEnd", null);
            } else {
                DateTime start = cn.hutool.core.date.DateUtil.offsetMonth(now, -(params.getMaxWorkYear() * 12));
                DateTime end = cn.hutool.core.date.DateUtil.offsetMonth(now, -(params.getMinWorkYear() * 12));
                queryMap.put("jobTimeBegin", start.toString(DatePattern.NORM_DATE_PATTERN));
                queryMap.put("jobTimeEnd", end.toString(DatePattern.NORM_DATE_PATTERN));
            }
        }
        //期望月薪
        if (params.getMinMoney() != null && params.getMaxMoney() != null) {
            queryMap.put("minMoney", params.getMinMoney());
            queryMap.put("maxMoney", params.getMaxMoney());
        }
        if (StrUtil.isNotBlank(params.getWorkIndustry())) {
            queryMap.put("workIndustry", params.getWorkIndustry() + ",");
        }
        //年龄
        if (params.getMinAge() != null) {
            String endBirthday = DateUtil.getYearFirst(params.getMinAge() - 1);
            queryMap.put("endBirthday", endBirthday);

        }
        if (params.getMaxAge() != null) {
            String beginBirthday = DateUtil.getYearFirst(params.getMaxAge());
            queryMap.put("beginBirthday", beginBirthday);
        }
        IPage<OpDeliveryHistory> opDeliveryHistoryPage = this.deliveryHistoryService.resumeTalentList(params.page(), queryMap);
        IPage<SsUserInfoVO> convert = opDeliveryHistoryPage.convert(opDeliveryHistory -> {
            SsUserInfoVO vo = new SsUserInfoVO();
            vo.setDataId(opDeliveryHistory.getId());
            //12.12修改为工作经历  院校信息  求职意向信息为中文简历种的信息
            CvResume resumeEn = resumeService.getById(opDeliveryHistory.getResumeId());
            LambdaQueryWrapper<CvUserEduInfo> eduQuery = new LambdaQueryWrapper<>();
            eduQuery.eq(CvUserEduInfo::getDelFlag, false).eq(CvUserEduInfo::getResumeId, resumeEn.getId()).orderByDesc(CvUserEduInfo::getEduLevel);
            List<CvUserEduInfo> eduInfos = eduInfoService.list(eduQuery);
            vo.setEduInfo(eduInfoConvert.toVO(eduInfos));
            OpJob job = jobService.getById(opDeliveryHistory.getJobId());
            vo.setJobName(job.getJobName());
            vo.setJobTime(opDeliveryHistory.getCreateTime());
            vo.setJob(jobConvert.toVO(job));
            CvResume resume = resumeService.getById(opDeliveryHistory.getResumeId());
            List<CvResumeVO> resumevos = new ArrayList<>();
            resumevos.add(resumeConvert.toVO(resume));
            vo.setCvResumeList(resumevos);
            vo.setReId(resume.getId());
            LambdaQueryWrapper<PiInfo> infoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            infoLambdaQueryWrapper.eq(PiInfo::getDelFlag, false).eq(PiInfo::getUserId, opDeliveryHistory.getUserId());
            PiInfo piInfo = piInfoService.getOne(infoLambdaQueryWrapper);
            vo.setUserInfo(enPiInfoConvert.toVO(piInfo));
            LambdaQueryWrapper<CvUserWorkInfo> workInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            workInfoLambdaQueryWrapper.eq(CvUserWorkInfo::getDelFlag, false)
                .eq(CvUserWorkInfo::getResumeId, opDeliveryHistory.getResumeId())
                .orderByDesc(CvUserWorkInfo::getCreateTime);
            List<CvUserWorkInfo> workInfos = workInfoService.list(workInfoLambdaQueryWrapper);
            vo.setWorkInfo(workInfoConvert.toVO(workInfos));
            vo.getUserInfo().setWorkYears(piInfo.getWorkYears());
            LambdaQueryWrapper<CvWorkIntention> workIntentionLambdaQueryWrapper = new LambdaQueryWrapper<>();
            workIntentionLambdaQueryWrapper.eq(CvWorkIntention::getDelFlag, false)
                .eq(CvWorkIntention::getResumeId, opDeliveryHistory.getResumeId())
                .orderByDesc(CvWorkIntention::getCreateTime);
            List<CvWorkIntention> workIntentions = workIntentionService.list(workIntentionLambdaQueryWrapper);
            vo.setWorkIntention(workIntentionConvert.toVO(workIntentions));
            //证书
            List<CvCertificate> certificateList = cvCertificateService.lambdaQuery()
                .eq(CvCertificate::getDelFlag, false)
                .eq(CvCertificate::getUserId, piInfo.getUserId())
                .list();
            vo.setCertificateList(this.cvCertificateConvert.toVO(certificateList));
            //浏览量
            int viewCount = browseHistoryService.lambdaQuery().eq(OpBrowseHistory::getDelFlag, false).eq(OpBrowseHistory::getUserId, opDeliveryHistory.getUserId()).count();
            vo.setBrowseCount(viewCount);
            int deCount = deliveryHistoryService.lambdaQuery().eq(OpDeliveryHistory::getDelFlag, false).eq(OpDeliveryHistory::getUserId, opDeliveryHistory.getUserId()).count();
            if (viewCount != 0) {
                vo.setDeliveryRate(new BigDecimal(deCount).divide(new BigDecimal(viewCount), 2).setScale(2, BigDecimal.ROUND_HALF_UP));
            }
            return vo;
        });
        return Result.ok(convert);
    }

    /**
     * 人才库查询条件构造
     *
     * @param queryWrapper
     * @param params
     * @param depart
     * @return
     */
    private Boolean createPageResultWrapper(LambdaQueryWrapper<OpDeliveryHistory> queryWrapper, EntryParam params, SysUserDepart depart) {
        //屏蔽
        List<OpShielding> shieldingList = opShieldingService.lambdaQuery().eq(OpShielding::getComId, depart.getDepId()).eq(OpShielding::getDelFlag, false).list();
        if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isNotEmpty(shieldingList)) {
            queryWrapper.notIn(OpDeliveryHistory::getUserId, shieldingList.stream().map(OpShielding::getUserId).toArray());
        }
        // 0 未阅读 1 已阅读  2 不合适 3 通过筛选 4  面试 5已发offer(已录用)6 已入职 7 被过滤
        if (params.getState() != null) {
            if (params.getState() == 0) {
                queryWrapper.in(OpDeliveryHistory::getState, 0, 1);
            } else {
                queryWrapper.eq(OpDeliveryHistory::getState, params.getState());
            }
        }
        if (params.getMaritalStatus() != null) {
            LambdaQueryWrapper<PiInfo> infoQuery = new LambdaQueryWrapper<>();
            infoQuery.eq(PiInfo::getMaritalStatus, params.getMaritalStatus());
            List<PiInfo> piInfoList = piInfoService.list(infoQuery);
            if (CollectionUtils.isEmpty(piInfoList)) {
                return false;
            }
            List<String> userIds = new ArrayList<>();
            piInfoList.forEach(e ->
                userIds.add(e.getUserId())
            );
            queryWrapper.in(OpDeliveryHistory::getUserId, userIds);
        }
        if (StringUtils.isNotBlank(params.getUserName())) {
            LambdaQueryWrapper<PiInfo> infoQuery = new LambdaQueryWrapper<>();
            infoQuery.like(PiInfo::getName, params.getUserName()).eq(PiInfo::getDelFlag, false);
            List<PiInfo> piInfoList = piInfoService.list(infoQuery);
            if (CollectionUtils.isEmpty(piInfoList)) {
                return false;
            }
            List<String> userIds = new ArrayList<>();
            piInfoList.forEach(e ->
                userIds.add(e.getUserId())
            );
            queryWrapper.in(OpDeliveryHistory::getUserId, userIds);
        }
        if (params.getMinAge() != null) {
            LambdaQueryWrapper<PiInfo> piInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            String time = DateUtil.getYearFirst(params.getMinAge() - 1);
            piInfoLambdaQueryWrapper.le(PiInfo::getBirthday, time).eq(PiInfo::getDelFlag, false);
            List<PiInfo> piInfoList = piInfoService.list(piInfoLambdaQueryWrapper);
            if (CollectionUtils.isEmpty(piInfoList)) {
                return false;
            }
            List<String> userIds = new ArrayList<>();
            piInfoList.forEach(e ->
                userIds.add(e.getUserId())
            );
            queryWrapper.in(OpDeliveryHistory::getUserId, userIds);
        }
        if (params.getMaxAge() != null) {
            LambdaQueryWrapper<PiInfo> piInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            String time = DateUtil.getYearFirst(params.getMaxAge() - 1);
            piInfoLambdaQueryWrapper.ge(PiInfo::getBirthday, time).eq(PiInfo::getDelFlag, false);
            List<PiInfo> piInfoList = piInfoService.list(piInfoLambdaQueryWrapper);
            if (CollectionUtils.isEmpty(piInfoList)) {
                return false;
            }
            List<String> userIds = new ArrayList<>();
            piInfoList.forEach(e -> {
                userIds.add(e.getUserId());
            });
            queryWrapper.in(OpDeliveryHistory::getUserId, userIds);
        }
        if (params.getEduLevel() != null) {
            //0 初中  1 高中 2 中专/中技 3 大专 4 本科 5 硕士 6 MBA/EMBA  7 博士
            LambdaQueryWrapper<CvUserEduInfo> eduQuery = new LambdaQueryWrapper<>();
            eduQuery.eq(CvUserEduInfo::getDelFlag, false).eq(CvUserEduInfo::getEduLevel, params.getEduLevel());
            List<CvUserEduInfo> eduInfos = eduInfoService.list(eduQuery);
            if (CollectionUtils.isEmpty(eduInfos)) {
                return false;
            }
            List<String> userIds = new ArrayList<>();
            eduInfos.forEach(e -> {
                userIds.add(e.getUserId());
            });
            queryWrapper.in(OpDeliveryHistory::getUserId, userIds);
        }
        return true;
    }

    /**
     * 人才库查询条件构造-two
     *
     * @param queryWrapper
     * @param params
     * @return
     */
    private Boolean createPageResultWrapperTwo(LambdaQueryWrapper<OpDeliveryHistory> queryWrapper, EntryParam params) {
        if (params.getSex() != null) {
            LambdaQueryWrapper<PiInfo> infoQuery = new LambdaQueryWrapper<>();
            infoQuery.eq(PiInfo::getSex, params.getSex()).eq(PiInfo::getDelFlag, false);
            List<PiInfo> piInfoList = piInfoService.list(infoQuery);
            if (CollectionUtils.isEmpty(piInfoList)) {
                return false;
            } else {
                List<String> userIds = new ArrayList<>();
                piInfoList.forEach(e -> {
                    userIds.add(e.getUserId());
                });
                queryWrapper.in(OpDeliveryHistory::getUserId, userIds);
            }
        }
        if (params.getMinMoney() != null && params.getMaxMoney() != null) {
            List<CvWorkIntention> workIntentions = workIntentionService.lambdaQuery().ge(CvWorkIntention::getMinMoney, params.getMinMoney()).le(CvWorkIntention::getMaxMoney, params.getMaxMoney()).select(CvWorkIntention::getUserId).list();
            if (CollectionUtils.isEmpty(workIntentions)) {
                return false;
            } else {
                List<String> userIds = new ArrayList<>();
                workIntentions.forEach(e -> {
                    userIds.add(e.getUserId());
                });
                queryWrapper.in(OpDeliveryHistory::getUserId, userIds);
            }
        }
        if (StringUtils.isNotBlank(params.getWorkIndustry())) {
            String[] ids = params.getWorkIndustry().split(",");
            String id = ids[ids.length - 1];
            List<CvWorkIntention> workIntentions = workIntentionService.lambdaQuery().like(CvWorkIntention::getWorkIndustry, id).eq(CvWorkIntention::getDelFlag, false).select(CvWorkIntention::getUserId, CvWorkIntention::getResumeId).list();
            if (CollectionUtils.isEmpty(workIntentions)) {
                return false;
            } else {
                List<String> userIds = new ArrayList<>();
                workIntentions.forEach(e -> {
                    CvResume resume = resumeService.getById(e.getResumeId());
                    if (resume != null && resume.getLanType() != null && resume.getLanType() == 0) {
                        userIds.add(e.getUserId());
                    }
                });
                if (CollectionUtils.isEmpty(userIds)) {
                    return false;
                }
                queryWrapper.in(OpDeliveryHistory::getUserId, userIds);
            }
        }
        if (StringUtils.isNotBlank(params.getJobName())) {
            List<RecruitmentPosition> positions = positionService.lambdaQuery().like(RecruitmentPosition::getName, params.getJobName()).select(RecruitmentPosition::getId, RecruitmentPosition::getName).list();
            if (!CollectionUtils.isEmpty(positions)) {
                StringBuilder sql = new StringBuilder("select max(create_time) as create_time,resume_id,user_id  from cv_user_work_info where  ");
                positions.forEach(e -> {
                    sql.append("(position_name like '%" + e.getId() + ",') or ");
                });
                sql.delete(sql.length() - 3, sql.length());
                sql.append(" group by user_id");
                List<CvUserWorkInfo> workIntentions = jdbcTemplate.query(sql.toString(), new BeanPropertyRowMapper<>(CvUserWorkInfo.class));
                if (CollectionUtils.isEmpty(workIntentions)) {
                    return false;
                } else {
                    Set<String> userIds = new HashSet<>();
                    workIntentions.forEach(e -> {
                        CvResume resume = resumeService.getById(e.getResumeId());
                        if (resume != null && resume.getLanType() != null && resume.getLanType() == 0) {
                            userIds.add(e.getUserId());
                        }
                    });
                    queryWrapper.in(OpDeliveryHistory::getUserId, userIds);
                }
            } else {
                return false;
            }
        }
        return true;
    }

    /**
     * 人才库查询条件构造-three
     *
     * @param queryWrapper
     * @param params
     * @return
     */
    private Boolean createPageResultWrapperThree(LambdaQueryWrapper<OpDeliveryHistory> queryWrapper, EntryParam params) {
        if (params.getMinWorkYear() != null && params.getMaxWorkYear() != null) {
            LambdaQueryWrapper<PiInfo> infoQuery = new LambdaQueryWrapper<>();
            if (params.getMinWorkYear() != null && params.getMaxWorkYear() != null) {
                int maxWorkYear = 999;
                if (params.getMinWorkYear() == 0 && params.getMaxWorkYear() == maxWorkYear) {

                } else if (params.getMinWorkYear() == 0 && params.getMaxWorkYear() == 0) {
                    infoQuery.isNull(PiInfo::getJobTime);
                } else {
                    String start = DateUtil.getYearFirst(params.getMaxWorkYear());
                    String end = DateUtil.getYearLast(params.getMinWorkYear());
                    infoQuery.ge(PiInfo::getJobTime, start).le(PiInfo::getJobTime, end);
                }

            }
            List<PiInfo> piInfoList = piInfoService.list(infoQuery);
            if (CollectionUtils.isEmpty(piInfoList)) {
                return false;
            } else {
                List<String> userIds = new ArrayList<>();
                piInfoList.forEach(e -> {
                    userIds.add(e.getUserId());
                });
                queryWrapper.in(OpDeliveryHistory::getUserId, userIds);
            }
        }
        return true;
    }

    /**
     * 应聘记录
     *
     * @param params
     * @return
     */
    @GetMapping("/applyList")
    @AutoLog(logType = 2, ty = "visit", value = "应聘记录列表查询")
    public Result<Page<ApplicationHistoryVO>> applyHis(ApplicationHistoryParams params) {
        LambdaQueryWrapper<OpDeliveryHistory> deliveryQuery = new LambdaQueryWrapper<>();
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        SysUserDepart depart = userDepartService.lambdaQuery().eq(SysUserDepart::getUserId, loginUser.getId()).one();
        deliveryQuery.eq(OpDeliveryHistory::getDelFlag, false).eq(OpDeliveryHistory::getUserId, params.getUserId()).eq(OpDeliveryHistory::getCompanyId, depart.getDepId()).orderByDesc(OpDeliveryHistory::getCreateTime);
        IPage<OpDeliveryHistory> page = deliveryHistoryService.page(params.page(), deliveryQuery);

        Function<OpDeliveryHistory, ApplicationHistoryVO> function = deliveryHistory -> {
            CvResume resume = this.resumeService.getById(deliveryHistory.getResumeId());
            ApplicationHistoryVO res = new ApplicationHistoryVO();
            res.setDeliveryInfo(deliveryHistoryConvert.toVO(deliveryHistory));
            OpJob job = jobService.getById(deliveryHistory.getJobId());
            res.setJobInfo(jobConvert.toVO(job));
            res.setResumeType(resume.getResumeType());
            return res;
        };
        return Result.ok((Page) page.convert(function));
    }
}
